/**********************************************************************
 *
 * This code is developed for the course Informatica Industrial II
 * of Universidad Carlos III de Madrid - 2012
 * Authors: Victor González-Pacheco, Alberto Valero-Gomez
 *
 * The code is licenced under the Common Creative License,
 * Attribution-ShareAlike 3.0
 *
 * You are free:
 *   - to Share - to copy, distribute and transmit the work
 *   - to Remix - to adapt the work
 *
 * Under the following conditions:
 *   - Attribution. You must attribute the work in the manner specified
 *     by the author or licensor (but not in any way that suggests that
 *     they endorse you or your use of the work).
 *   - Share Alike. If you alter, transform, or build upon this work,
 *     you may distribute the resulting work only under the same or
 *     similar license to this one.
 *
 * Any of the above conditions can be waived if you get permission
 * from the copyright holder.  Nothing in this license impairs or
 * restricts the author's moral rights.
 *
 * It is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 * PURPOSE.
 **********************************************************************/

#include "UDPSocket.h"

#include <string.h>
#include <sys/socket.h>
#include <sstream>
#include <netdb.h>
#include <unistd.h>


UDPSocket::UDPSocket(string rem_ip, int rem_port, string local_ip, int local_port) throw(string):
    AbstractSocket(rem_ip,rem_port,local_ip,local_port)
{
    try{
        open();
    }catch(string e){
        throw(e);
    }
}

UDPSocket::UDPSocket(int fd):
    AbstractSocket(fd)
{}


int UDPSocket::write (const string & cad, int trials) const throw (char const *)
{
    for (int i=0; i<trials; i++){
        int bytes = ::write(_socket_fd, cad.c_str(), cad.size());
        if( bytes >= 0 ) return bytes;
    }
    throw("Cannot write to socket");
}

string UDPSocket::read() const throw (char const *)
{
    char buffer[256];
    bzero(buffer,256);
    int n = ::read(_socket_fd,buffer,255);
    if (n < 0){
        stringstream strstr;
        strstr << "Error reading\n"
               << "Error number "
               << errno
               << ": "
               << strerror(errno)
               << " ";

        throw(strstr.str().c_str());
    }
    string rstring = buffer;
    return rstring;
}

int UDPSocket::open() throw(char const *){
    _socket_fd = socket(AF_INET, SOCK_STREAM, 0);
    if (_socket_fd < 0){
        throw("ERROR opening socket");
        return _socket_fd;
    }
    return _socket_fd;
}

